/**
    @file frame.h
    @brief defines the frame prototypes
*/
/**    @defgroup frame Frame
    The Module of the frame
    @{
*/

#ifndef __FRAME_H__
#define __FRAME_H__

#include "temp.h"
#include "tree.h"

typedef struct F_frame_ *F_frame;
typedef struct F_access_ *F_access;

typedef struct F_accessList_ *F_accessList;
struct F_accessList_ { F_access data; F_accessList next;};

Temp_temp F_RA();   // ?
Temp_temp F_RV();   ///< return the register to save fun's return value
Temp_temp F_FP();   ///< return the frame pointer register
Temp_temp F_SP();   ///< return the stack pointer register
Temp_temp F_ZERO(); ///< return the zero register(register always store 0)

Temp_map F_tempMap;
Temp_tempList F_registers();
string F_getlabel(F_frame frame);

int F_getRegNum();    ///< return the number of the generic registers

/// Get the name of a temp var
string F_getTempName(Temp_temp temp);

/// Get the size of a single data unit
int F_singleSize(); 

/** Generate instruction to accesss a simple var
    @param access access of a variable
    @param framePtr pointer to a frame you wanna lookup
    @return assembly instructions to get the var
*/
T_exp F_Exp(F_access access, T_exp framePtr); 

/** Call external functions
    @param s name of the external function
    @param args arguments for the function
    @return assembly instructions to call the function
*/
T_exp F_externalCall(string s, T_expList args);

/// Create a new frame
F_frame     F_newFrame(Temp_label name, U_boolList formals);

Temp_label     F_name(F_frame f);
F_accessList     F_formals(F_frame f);
F_access     F_allocLocal(F_frame f, bool escape, unsigned size);

/**F_access structure stores the infomation that whether a variable is stored 
in memory or register, and the location of it.
*/
struct F_access_
{
    enum { inFrame, inReg } kind;
    union
    {
        int offset;     // in frame
        Temp_temp reg;     // in reg
    } u;
};

#endif
///@}

